﻿using System;
using System.Xml.Linq;
using IcicleFramework.Components;
using IcicleFramework.Entities;

namespace IcicleFramework.GameServices
{
    /// <summary>
    /// A factory for generating generic components.
    /// It assumes that the components themselves can populate their fields
    /// based on some XML definition for the given component.
    /// </summary>
    public class ComponentFactory : GameService, IComponentFactory
    {
        public IBaseComponent GenerateComponent(XElement element)
        {
            IBaseComponent component = null;

            //As long as we have a defined class and type, try to instantiate the corresponding component.
            if (element.Attribute("class") != null && element.Attribute("type") != null)
            {
                string assembly;

                if (element.Attribute("assembly") != null)
                {
                    assembly = element.Attribute("assembly").Value;
                }
                else
                {
                    string[] temp = element.Attribute("class").Value.Split('.');
                    assembly = temp[0];
                }

                Type classType = Type.GetType(String.Format("{0},{1}", element.Attribute("class").Value, assembly));
                string stringInterface = element.Attribute("type").Value;

                //Find the proper interface designated by the entity definition so we can store it properly in the GameObject...
                Type interfaceType = Helper.FindInterface(classType, stringInterface);

                component = (IBaseComponent) Activator.CreateInstance(classType);
                component.Deserialize(element);
                component.BaseType = interfaceType;
            }

            return component;
        }

        public IBaseComponent GenerateComponent(XElement element, IGameObject parent)
        {
            IBaseComponent component = null;

            if (element.Attribute("class") != null && element.Attribute("type") != null)
            {
                string assembly;

                if (element.Attribute("assembly") != null)
                    assembly = element.Attribute("assembly").Value;
                else
                {
                    string[] temp = element.Attribute("class").Value.Split('.');
                    assembly = temp[0];
                }

                Type classType = Type.GetType(String.Format("{0},{1}", element.Attribute("class").Value, assembly));
                string stringInterface = element.Attribute("type").Value;

                //Find the proper interface designated by the entity definition so we can store it properly in the GameObject...
                Type interfaceType = Helper.FindInterface(classType, stringInterface);

                component = (IBaseComponent)Activator.CreateInstance(classType);
                component.Parent = parent;
                component.Deserialize(element);
                component.BaseType = interfaceType;
            }

            return component;
        }
    }
}
